﻿using System;
using System.Collections.Generic;
using System.Text;

namespace TCCHWLib.Commands
{
    public enum ParameterType { Value, Address, Variable,Instruction,Null }

    public abstract class ICommand: IDisposable
    {
        protected object m_Value;
        private int m_NextPC = -1;
        private BatchCommand m_ParentBatch = null;
        protected object m_Operand1;
        protected object m_Operand2;
        protected object m_Operand3;


        protected ParameterType m_Type1;
        protected ParameterType m_Type2;
        protected ParameterType m_Type3;

        protected object m_ExOperand1;
        protected object m_ExOperand2;
        protected object m_ExOperand3;

        protected ParameterType m_ExType1;
        protected ParameterType m_ExType2;
        protected ParameterType m_ExType3;

        public object ExOperand1
        {
            get { return m_ExOperand1; }
            set { m_ExOperand1 = value; }
        }
        public object ExOperand2
        {
            get { return m_ExOperand2; }
            set { m_ExOperand2 = value; }
        }
        public object ExOperand3
        {
            get { return m_ExOperand3; }
            set { m_ExOperand3 = value; }
        }

        public ParameterType ExType1
        {
            get { return m_ExType1; }
            set { m_ExType1 = value; }
        }
        public ParameterType ExType2
        {
            get { return m_ExType2; }
            set { m_ExType2 = value; }
        }
        public ParameterType ExType3
        {
            get { return m_ExType3; }
            set { m_ExType3 = value; }
        }

        
        public object Operand3
        {
            get { return m_Operand3; }
            set { m_Operand3 = value; }
        }
        public  ParameterType Type3
        {
            get { return m_Type3; }
            set { m_Type3 = value; }
        }

        public BatchCommand ParentBatch
        {
            get { return m_ParentBatch; }
            set { m_ParentBatch = value; }
        }

        public object Operand1
        {
            get { return m_Operand1; }
            set { m_Operand1 = value; }
        }

        public object Operand2
        {
            get { return m_Operand2; }
            set { m_Operand2 = value; }
        }

        public ParameterType Type1
        {
            get { return m_Type1; }
            set { m_Type1 = value; }
        }

        public ParameterType Type2
        {
            get { return m_Type2; }
            set { m_Type2 = value; }
        }
 
        public int NextPC
        {
            get { return m_NextPC; }
            set { m_NextPC = value; }
        }

        public object Value
        {
            get { return m_Value; }
            set { m_Value = value; }
        }

        public abstract object Execute(Processor processor);

        public virtual void ExecuteGlobal(Processor processor)
        {
            return;
        }

        public virtual void UpdatePC(Processor processor)
        {
            if (m_NextPC == -1)

                processor.PC++;
            else
                processor.PC = NextPC;
        }

        public virtual void Undo(Processor processor)
        {

            m_Value = null;
            return;

        }
        
        public override string ToString()
        {
            return this.GetType().Name.Replace("Command", "").ToUpper()+String.Format(" > type1={0}, type2={1},operand 1 {2}, operand 2 {3},next pc{4}", m_Type1, m_Type2,m_Operand1,m_Operand2,NextPC);
        }

        #region IDisposable Members

        public void Dispose()
        {
        }

        #endregion

    }
}
